package hawk.example.bookstore.update;

import static glz.hawkframework.support.ArgumentSupport.*;

import glz.hawkframework.dao.base.function.ColumnDescriptor;
import glz.hawkframework.dao.base.function.ColumnFunction;
import glz.hawkframework.dao.base.function.IRecord;
import glz.hawkframework.dao.base.function.RecordCreateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordCreateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordIdFunction;
import glz.hawkframework.dao.base.function.RecordUpdateDateTimeFunction;
import glz.hawkframework.dao.base.function.RecordUpdateUserIdFunction;
import glz.hawkframework.dao.base.function.RecordVersionFunction;
import glz.hawkframework.sql.support.SqlColumn;
import glz.hawkframework.sql.support.impl.DefaultValueColumn;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Map to table: BOOK
 */
public class BookColumnUpdate implements IRecord {
    /**
     * Map to column: BOOK_ID
     */
    private SqlColumn bookId;
    /**
     * Map to column: BOOK_ID
     */
    private boolean bookIdUpdated = false;
    /**
     * ISBN
     * <p>Map to column: ISBN</p>
     */
    private SqlColumn isbn;
    /**
     * ISBN
     * <p>Map to column: ISBN</p>
     */
    private boolean isbnUpdated = false;
    /**
     * 书名
     * <p>Map to column: TITLE</p>
     */
    private SqlColumn title;
    /**
     * 书名
     * <p>Map to column: TITLE</p>
     */
    private boolean titleUpdated = false;
    /**
     * 书单价
     * <p>Map to column: PRICE</p>
     */
    private SqlColumn price;
    /**
     * 书单价
     * <p>Map to column: PRICE</p>
     */
    private boolean priceUpdated = false;
    /**
     * 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    private SqlColumn publishDate;
    /**
     * 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    private boolean publishDateUpdated = false;
    /**
     * Map to column: BOOK_CATEGORY
     */
    private SqlColumn bookCategory;
    /**
     * Map to column: BOOK_CATEGORY
     */
    private boolean bookCategoryUpdated = false;
    /**
     * Map to column: PUBLISHER_ID
     */
    private SqlColumn publisherId;
    /**
     * Map to column: PUBLISHER_ID
     */
    private boolean publisherIdUpdated = false;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private SqlColumn createDateTime;
    /**
     * Map to column: CREATE_DATE_TIME
     */
    private boolean createDateTimeUpdated = false;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private SqlColumn updateDateTime;
    /**
     * Map to column: UPDATE_DATE_TIME
     */
    private boolean updateDateTimeUpdated = false;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private SqlColumn deleteDateTime;
    /**
     * Map to column: DELETE_DATE_TIME
     */
    private boolean deleteDateTimeUpdated = false;
    /**
     * Map to column: CREATE_USER_ID
     */
    private SqlColumn createUserId;
    /**
     * Map to column: CREATE_USER_ID
     */
    private boolean createUserIdUpdated = false;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private SqlColumn updateUserId;
    /**
     * Map to column: UPDATE_USER_ID
     */
    private boolean updateUserIdUpdated = false;
    /**
     * Map to column: DELETE_USER_ID
     */
    private SqlColumn deleteUserId;
    /**
     * Map to column: DELETE_USER_ID
     */
    private boolean deleteUserIdUpdated = false;
    /**
     * Map to column: RECORD_VERSION
     */
    private SqlColumn recordVersion;
    /**
     * Map to column: RECORD_VERSION
     */
    private boolean recordVersionUpdated = false;
    /**
     * This map holds the relations between function class and column
     */
    private final Map<Class<? extends ColumnFunction>, ColumnDescriptor<?>> functionMap = new HashMap<>();

    {
        functionMap.put(RecordIdFunction.class, new ColumnDescriptor<>("BOOK_ID", "bookId", this::getBookId, this::isBookIdUpdated, this::setBookId));
        functionMap.put(RecordCreateDateTimeFunction.class, new ColumnDescriptor<>("CREATE_DATE_TIME", "createDateTime", this::getCreateDateTime, this::isCreateDateTimeUpdated, this::setCreateDateTime));
        functionMap.put(RecordUpdateDateTimeFunction.class, new ColumnDescriptor<>("UPDATE_DATE_TIME", "updateDateTime", this::getUpdateDateTime, this::isUpdateDateTimeUpdated, this::setUpdateDateTime));
        functionMap.put(RecordCreateUserIdFunction.class, new ColumnDescriptor<>("CREATE_USER_ID", "createUserId", this::getCreateUserId, this::isCreateUserIdUpdated, this::setCreateUserId));
        functionMap.put(RecordUpdateUserIdFunction.class, new ColumnDescriptor<>("UPDATE_USER_ID", "updateUserId", this::getUpdateUserId, this::isUpdateUserIdUpdated, this::setUpdateUserId));
        functionMap.put(RecordVersionFunction.class, new ColumnDescriptor<>("RECORD_VERSION", "recordVersion", this::getRecordVersion, this::isRecordVersionUpdated, this::setRecordVersion));
    }

    /**
     * Map to column: BOOK_ID
     */
    public SqlColumn getBookId() {
        return bookId;
    }

    /**
     * Map to column: BOOK_ID
     */
    public boolean isBookIdUpdated() {
        return bookIdUpdated;
    }

    /**
     * Map to column: BOOK_ID
     */
    public void setBookId(BigInteger bookId) {
        this.bookId = bookId == null ? null : new DefaultValueColumn(bookId);
        this.bookIdUpdated = true;
    }

    /**
     * Map to column: BOOK_ID
     */
    public void setBookId(SqlColumn bookId) {
        this.bookId = bookId;
        this.bookIdUpdated = true;
    }

    /**
     * Gets ISBN
     * <p>Map to column: ISBN</p>
     */
    public SqlColumn getIsbn() {
        return isbn;
    }

    /**
     * Gets ISBN
     * <p>Map to column: ISBN</p>
     */
    public boolean isIsbnUpdated() {
        return isbnUpdated;
    }

    /**
     * Sets ISBN
     * <p>Map to column: ISBN</p>
     */
    public void setIsbn(String isbn) {
        this.isbn = isbn == null ? null : new DefaultValueColumn(isbn);
        this.isbnUpdated = true;
    }

    /**
     * Sets ISBN
     * <p>Map to column: ISBN</p>
     */
    public void setIsbn(SqlColumn isbn) {
        this.isbn = isbn;
        this.isbnUpdated = true;
    }

    /**
     * Gets 书名
     * <p>Map to column: TITLE</p>
     */
    public SqlColumn getTitle() {
        return title;
    }

    /**
     * Gets 书名
     * <p>Map to column: TITLE</p>
     */
    public boolean isTitleUpdated() {
        return titleUpdated;
    }

    /**
     * Sets 书名
     * <p>Map to column: TITLE</p>
     */
    public void setTitle(String title) {
        this.title = title == null ? null : new DefaultValueColumn(title);
        this.titleUpdated = true;
    }

    /**
     * Sets 书名
     * <p>Map to column: TITLE</p>
     */
    public void setTitle(SqlColumn title) {
        this.title = title;
        this.titleUpdated = true;
    }

    /**
     * Gets 书单价
     * <p>Map to column: PRICE</p>
     */
    public SqlColumn getPrice() {
        return price;
    }

    /**
     * Gets 书单价
     * <p>Map to column: PRICE</p>
     */
    public boolean isPriceUpdated() {
        return priceUpdated;
    }

    /**
     * Sets 书单价
     * <p>Map to column: PRICE</p>
     */
    public void setPrice(BigDecimal price) {
        this.price = price == null ? null : new DefaultValueColumn(price);
        this.priceUpdated = true;
    }

    /**
     * Sets 书单价
     * <p>Map to column: PRICE</p>
     */
    public void setPrice(SqlColumn price) {
        this.price = price;
        this.priceUpdated = true;
    }

    /**
     * Gets 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    public SqlColumn getPublishDate() {
        return publishDate;
    }

    /**
     * Gets 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    public boolean isPublishDateUpdated() {
        return publishDateUpdated;
    }

    /**
     * Sets 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    public void setPublishDate(LocalDate publishDate) {
        this.publishDate = publishDate == null ? null : new DefaultValueColumn(publishDate);
        this.publishDateUpdated = true;
    }

    /**
     * Sets 书出版日期
     * <p>Map to column: PUBLISH_DATE</p>
     */
    public void setPublishDate(SqlColumn publishDate) {
        this.publishDate = publishDate;
        this.publishDateUpdated = true;
    }

    /**
     * Map to column: BOOK_CATEGORY
     */
    public SqlColumn getBookCategory() {
        return bookCategory;
    }

    /**
     * Map to column: BOOK_CATEGORY
     */
    public boolean isBookCategoryUpdated() {
        return bookCategoryUpdated;
    }

    /**
     * Map to column: BOOK_CATEGORY
     */
    public void setBookCategory(String bookCategory) {
        this.bookCategory = bookCategory == null ? null : new DefaultValueColumn(bookCategory);
        this.bookCategoryUpdated = true;
    }

    /**
     * Map to column: BOOK_CATEGORY
     */
    public void setBookCategory(SqlColumn bookCategory) {
        this.bookCategory = bookCategory;
        this.bookCategoryUpdated = true;
    }

    /**
     * Map to column: PUBLISHER_ID
     */
    public SqlColumn getPublisherId() {
        return publisherId;
    }

    /**
     * Map to column: PUBLISHER_ID
     */
    public boolean isPublisherIdUpdated() {
        return publisherIdUpdated;
    }

    /**
     * Map to column: PUBLISHER_ID
     */
    public void setPublisherId(BigInteger publisherId) {
        this.publisherId = publisherId == null ? null : new DefaultValueColumn(publisherId);
        this.publisherIdUpdated = true;
    }

    /**
     * Map to column: PUBLISHER_ID
     */
    public void setPublisherId(SqlColumn publisherId) {
        this.publisherId = publisherId;
        this.publisherIdUpdated = true;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public SqlColumn getCreateDateTime() {
        return createDateTime;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public boolean isCreateDateTimeUpdated() {
        return createDateTimeUpdated;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public void setCreateDateTime(LocalDateTime createDateTime) {
        this.createDateTime = createDateTime == null ? null : new DefaultValueColumn(createDateTime);
        this.createDateTimeUpdated = true;
    }

    /**
     * Map to column: CREATE_DATE_TIME
     */
    public void setCreateDateTime(SqlColumn createDateTime) {
        this.createDateTime = createDateTime;
        this.createDateTimeUpdated = true;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public SqlColumn getUpdateDateTime() {
        return updateDateTime;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public boolean isUpdateDateTimeUpdated() {
        return updateDateTimeUpdated;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public void setUpdateDateTime(LocalDateTime updateDateTime) {
        this.updateDateTime = updateDateTime == null ? null : new DefaultValueColumn(updateDateTime);
        this.updateDateTimeUpdated = true;
    }

    /**
     * Map to column: UPDATE_DATE_TIME
     */
    public void setUpdateDateTime(SqlColumn updateDateTime) {
        this.updateDateTime = updateDateTime;
        this.updateDateTimeUpdated = true;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public SqlColumn getDeleteDateTime() {
        return deleteDateTime;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public boolean isDeleteDateTimeUpdated() {
        return deleteDateTimeUpdated;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public void setDeleteDateTime(LocalDateTime deleteDateTime) {
        this.deleteDateTime = deleteDateTime == null ? null : new DefaultValueColumn(deleteDateTime);
        this.deleteDateTimeUpdated = true;
    }

    /**
     * Map to column: DELETE_DATE_TIME
     */
    public void setDeleteDateTime(SqlColumn deleteDateTime) {
        this.deleteDateTime = deleteDateTime;
        this.deleteDateTimeUpdated = true;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public SqlColumn getCreateUserId() {
        return createUserId;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public boolean isCreateUserIdUpdated() {
        return createUserIdUpdated;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public void setCreateUserId(String createUserId) {
        this.createUserId = createUserId == null ? null : new DefaultValueColumn(createUserId);
        this.createUserIdUpdated = true;
    }

    /**
     * Map to column: CREATE_USER_ID
     */
    public void setCreateUserId(SqlColumn createUserId) {
        this.createUserId = createUserId;
        this.createUserIdUpdated = true;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public SqlColumn getUpdateUserId() {
        return updateUserId;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public boolean isUpdateUserIdUpdated() {
        return updateUserIdUpdated;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public void setUpdateUserId(String updateUserId) {
        this.updateUserId = updateUserId == null ? null : new DefaultValueColumn(updateUserId);
        this.updateUserIdUpdated = true;
    }

    /**
     * Map to column: UPDATE_USER_ID
     */
    public void setUpdateUserId(SqlColumn updateUserId) {
        this.updateUserId = updateUserId;
        this.updateUserIdUpdated = true;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public SqlColumn getDeleteUserId() {
        return deleteUserId;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public boolean isDeleteUserIdUpdated() {
        return deleteUserIdUpdated;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public void setDeleteUserId(String deleteUserId) {
        this.deleteUserId = deleteUserId == null ? null : new DefaultValueColumn(deleteUserId);
        this.deleteUserIdUpdated = true;
    }

    /**
     * Map to column: DELETE_USER_ID
     */
    public void setDeleteUserId(SqlColumn deleteUserId) {
        this.deleteUserId = deleteUserId;
        this.deleteUserIdUpdated = true;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public SqlColumn getRecordVersion() {
        return recordVersion;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public boolean isRecordVersionUpdated() {
        return recordVersionUpdated;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public void setRecordVersion(Long recordVersion) {
        this.recordVersion = recordVersion == null ? null : new DefaultValueColumn(recordVersion);
        this.recordVersionUpdated = true;
    }

    /**
     * Map to column: RECORD_VERSION
     */
    public void setRecordVersion(SqlColumn recordVersion) {
        this.recordVersion = recordVersion;
        this.recordVersionUpdated = true;
    }

    @Override
    public Optional<ColumnDescriptor<?>> findColumnDescriptor(Class<? extends ColumnFunction> columnFunctionClass) {
        return Optional.ofNullable(functionMap.get(argNotNull(columnFunctionClass, "columnFunctionClass")));
    }
}
